package zgrjb.snbq.teach_platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import zgrjb.snbq.teach_platform.component.SmsComponent;
import zgrjb.snbq.teach_platform.constant.RedisKey;
import zgrjb.snbq.teach_platform.dto.model.User;
import zgrjb.snbq.teach_platform.dto.model.UserDO;
import zgrjb.snbq.teach_platform.dto.req.LoginRequest;
import zgrjb.snbq.teach_platform.dto.req.RegisterRequest;
import zgrjb.snbq.teach_platform.enums.BizCodeEnum;
import zgrjb.snbq.teach_platform.enums.SendCodeEnum;
import zgrjb.snbq.teach_platform.mapper.UserMapper;
import zgrjb.snbq.teach_platform.service.UserService;
import zgrjb.snbq.teach_platform.util.CommonUtil;
import zgrjb.snbq.teach_platform.util.IDUtil;
import zgrjb.snbq.teach_platform.util.JsonData;
import zgrjb.snbq.teach_platform.util.JwtUtil;

import jakarta.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    /**
     * 10分钟有效
     */
    private static final int CODE_EXPIRED = 60*1000*10;

    @Autowired
    private SmsComponent smsComponent;

    @Autowired
    private UserMapper attendeeMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public JsonData sendCode(SendCodeEnum userRegister, String phone) {
        String cacheKey = String.format(RedisKey.CHECK_CODE_KEY,userRegister.name(),phone);

        String cacheValue = redisTemplate.opsForValue().get(cacheKey);

        //如果不为空，再判断是否是60秒内重复发送 0122_232131321314132
        if(StringUtils.isNotBlank(cacheValue)){
            long ttl = Long.parseLong(cacheValue.split("_")[1]);
            //当前时间戳-验证码发送的时间戳，如果小于60秒，则不给重复发送
            long leftTime = CommonUtil.getCurrentTimestamp() - ttl;
            if( leftTime < (1000*60)){
                log.info("重复发送短信验证码，时间间隔:{}秒",leftTime);
                return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
            }
        }

        String code = CommonUtil.getRandomCode(6);
        //生成拼接好验证码
        String value = code+"_"+CommonUtil.getCurrentTimestamp();
        redisTemplate.opsForValue().set(cacheKey,value,CODE_EXPIRED, TimeUnit.MILLISECONDS);

        //发送手机验证码
        if (smsComponent != null) {
            smsComponent.send(phone,code);
        } else {
            // 开发环境，直接打印验证码
            log.info("开发环境验证码: {}", code);
        }
        return JsonData.buildSuccess();
    }

    @Override
    public JsonData register(RegisterRequest request) {
        String key = String.format(RedisKey.CHECK_CODE_KEY,SendCodeEnum.ATTENDEE_USER_REGISTER,request.getPhone());
        String value = redisTemplate.opsForValue().get(key);
        
        if (value == null) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }
        
        String code = value.split("_")[0];
        if(code.equals(request.getCode())){
            // 检查手机号是否已存在
            UserDO attendeeDO = attendeeMapper.selectOne(new QueryWrapper<UserDO>().eq("phone",request.getPhone()));
            if(attendeeDO==null){
                // 检查邮箱是否已存在
                if (request.getEmail() != null) {
                    UserDO emailUser = attendeeMapper.selectOne(new QueryWrapper<UserDO>().eq("email", request.getEmail()));
                    if (emailUser != null) {
                        return JsonData.buildResult(BizCodeEnum.ATTENDEE_ALREADY_EXIST);
                    }
                }
                
                UserDO attendee = new UserDO();
                attendee.setId((Long) IDUtil.geneSnowFlakeID());
                attendee.setName(request.getName());
                attendee.setPassword(CommonUtil.MD5(request.getPassword()));
                attendee.setHeadImg(request.getHeadImg());
                attendee.setPhone(request.getPhone());
                attendee.setEmail(request.getEmail());
                attendee.setType(request.getType());
                attendee.setStatus(1); // 默认状态为正常
                
                // 根据角色设置特定字段
                if ("teacher".equals(request.getType())) {
                    // 校验工号唯一
                    if (request.getTeacherNo() != null) {
                        UserDO noUser = attendeeMapper.selectOne(new QueryWrapper<UserDO>().eq("teacher_no", request.getTeacherNo()));
                        if (noUser != null) {
                            return JsonData.buildError("教师工号已存在");
                        }
                        attendee.setTeacherNo(request.getTeacherNo());
                    }
                    attendee.setDepartment(request.getDepartment());
                    attendee.setTitle(request.getTitle());
                    attendee.setSubject(request.getSubject());
                } else if ("student".equals(request.getType())) {
                    attendee.setStudentId(request.getStudentId());
                    attendee.setMajor(request.getMajor());
                    attendee.setClassName(request.getClassName());
                    attendee.setGrade(request.getGrade());
                }
                
                int result = attendeeMapper.insert(attendee);
                if (result > 0) {
                    // 删除验证码
                    redisTemplate.delete(key);
                    return JsonData.buildSuccess();
                } else {
                    return JsonData.buildResult(BizCodeEnum.ATTENDEE_REGISTER_ERROR);
                }
            }
            return JsonData.buildResult(BizCodeEnum.ATTENDEE_ALREADY_EXIST);
        }
        return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
    }

    @Override
    public JsonData login(LoginRequest request) {
        log.info("用户登录请求: 账号={}, 类型={}", request.getPhone(), request.getType());
        
        // 支持手机号或邮箱登录
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<UserDO>()
                .eq("password", CommonUtil.MD5(request.getPassword()))
                .eq("type", request.getType());
        
        // 判断是否为邮箱格式
        if (request.getPhone().contains("@")) {
            queryWrapper.eq("email", request.getPhone());
            log.info("邮箱登录: {}", request.getPhone());
        } else {
            queryWrapper.eq("phone", request.getPhone());
            log.info("手机号登录: {}", request.getPhone());
        }
        
        UserDO attendeeDO = attendeeMapper.selectOne(queryWrapper);
        
        if(attendeeDO != null){
            log.info("用户找到: id={}, name={}", attendeeDO.getId(), attendeeDO.getName());
            
            // 构建用户对象
            User loginUser = new User();
            loginUser.setId(attendeeDO.getId());
            loginUser.setPhone(attendeeDO.getPhone());
            loginUser.setEmail(attendeeDO.getEmail());
            loginUser.setHeadImg(attendeeDO.getHeadImg());
            loginUser.setName(attendeeDO.getName());
            loginUser.setType(attendeeDO.getType());
            
            // 根据角色设置特定字段
            if ("teacher".equals(attendeeDO.getType())) {
                loginUser.setDepartment(attendeeDO.getDepartment());
                loginUser.setTitle(attendeeDO.getTitle());
                loginUser.setSubject(attendeeDO.getSubject());
                loginUser.setTeacherNo(attendeeDO.getTeacherNo());
            } else if ("student".equals(attendeeDO.getType())) {
                loginUser.setStudentId(attendeeDO.getStudentId());
                loginUser.setMajor(attendeeDO.getMajor());
                loginUser.setClassName(attendeeDO.getClassName());
                loginUser.setGrade(attendeeDO.getGrade());
            }
            
            // 生成JWT token
            String token = JwtUtil.geneAttendeeJsonWebTokne(loginUser);
            log.info("JWT token 生成成功");
            
            // 将token设置到cookie中
            try {
                ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
                HttpServletResponse response = attr.getResponse();
                if (response != null) {
                    JwtUtil.setTokenToCookie(response, token);
                    log.info("JWT token已设置到cookie中");
                }
            } catch (Exception e) {
                log.warn("设置cookie失败: {}", e.getMessage());
            }
            
            // 返回用户信息和token
            Map<String, Object> data = new HashMap<>();
            data.put("token", token);
            data.put("userInfo", loginUser);
            
            log.info("用户登录成功: {}", loginUser.getName());
            return JsonData.buildSuccess(data);
        }
        
        log.warn("用户登录失败: 用户名或密码错误, 账号={}", request.getPhone());
        return JsonData.buildResult(BizCodeEnum.LOGIN_FALL);
    }

    @Override
    public UserDO getUserByTeacherNo(String teacherNo) {
        if (teacherNo == null) return null;
        return attendeeMapper.selectOne(new QueryWrapper<UserDO>().eq("teacher_no", teacherNo));
    }

    @Override
    public UserDO getUserByStudentId(String studentId) {
        if (studentId == null) return null;
        return attendeeMapper.selectOne(new QueryWrapper<UserDO>().eq("student_id", studentId));
    }

    @Override
    public UserDO getUserByName(String name) {
        if (name == null) return null;
        return attendeeMapper.selectOne(new QueryWrapper<UserDO>().like("name", name));
    }
}
